package com.blog.cmrpersonalblog.service.impl;

import com.blog.cmrpersonalblog.dto.notification.requset.NotificationSettingsUpdateRequest;
import com.blog.cmrpersonalblog.dto.notification.respnose.NotificationSettingsResponse;
import com.blog.cmrpersonalblog.entity.Notification;
import com.blog.cmrpersonalblog.entity.NotificationSettings;
import com.blog.cmrpersonalblog.mapper.NotificationSettingsMapper;
import com.blog.cmrpersonalblog.service.NotificationSettingsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalTime;

/**
 * 通知设置服务实现类
 */
@Slf4j
@Service
public class NotificationSettingsServiceImpl implements NotificationSettingsService {

    @Resource
    private NotificationSettingsMapper notificationSettingsMapper;

    @Override
    public NotificationSettingsResponse getUserSettings(Long userId) {
        log.info("获取用户通知设置: userId={}", userId);
        try {
            NotificationSettings settings = notificationSettingsMapper.selectByUserId(userId);
            
            // 如果用户没有设置，自动初始化
            if (settings == null) {
                log.info("用户通知设置不存在，自动初始化: userId={}", userId);
                initUserSettings(userId);
                settings = notificationSettingsMapper.selectByUserId(userId);
            }
            
            return convertToResponse(settings);
        } catch (Exception e) {
            log.error("获取用户通知设置失败: userId={}", userId, e);
            throw new RuntimeException("获取通知设置失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUserSettings(Long userId, NotificationSettingsUpdateRequest request) {
        log.info("更新用户通知设置: userId={}, request={}", userId, request);
        try {
            // 确保用户设置存在
            NotificationSettings existingSettings = notificationSettingsMapper.selectByUserId(userId);
            if (existingSettings == null) {
                initUserSettings(userId);
                existingSettings = notificationSettingsMapper.selectByUserId(userId);
            }
            
            // 构建更新对象
            NotificationSettings settings = new NotificationSettings();
            settings.setUserId(userId);
            
            // 复制非空字段
            if (request.getFollowEnabled() != null) {
                settings.setFollowEnabled(request.getFollowEnabled());
            }
            if (request.getLikeEnabled() != null) {
                settings.setLikeEnabled(request.getLikeEnabled());
            }
            if (request.getCommentEnabled() != null) {
                settings.setCommentEnabled(request.getCommentEnabled());
            }
            if (request.getReplyEnabled() != null) {
                settings.setReplyEnabled(request.getReplyEnabled());
            }
            if (request.getMentionEnabled() != null) {
                settings.setMentionEnabled(request.getMentionEnabled());
            }
            if (request.getSystemEnabled() != null) {
                settings.setSystemEnabled(request.getSystemEnabled());
            }
            if (request.getCollectEnabled() != null) {
                settings.setCollectEnabled(request.getCollectEnabled());
            }
            if (request.getDoNotDisturbEnabled() != null) {
                settings.setDoNotDisturbEnabled(request.getDoNotDisturbEnabled());
            }
            if (StringUtils.hasText(request.getDoNotDisturbStart())) {
                settings.setDoNotDisturbStart(LocalTime.parse(request.getDoNotDisturbStart()));
            }
            if (StringUtils.hasText(request.getDoNotDisturbEnd())) {
                settings.setDoNotDisturbEnd(LocalTime.parse(request.getDoNotDisturbEnd()));
            }
            if (request.getNotificationAggregationEnabled() != null) {
                settings.setNotificationAggregationEnabled(request.getNotificationAggregationEnabled());
            }
            if (request.getWebsocketEnabled() != null) {
                settings.setWebsocketEnabled(request.getWebsocketEnabled());
            }
            if (request.getEmailNotificationEnabled() != null) {
                settings.setEmailNotificationEnabled(request.getEmailNotificationEnabled());
            }
            if (request.getEmailFollowEnabled() != null) {
                settings.setEmailFollowEnabled(request.getEmailFollowEnabled());
            }
            if (request.getEmailCommentEnabled() != null) {
                settings.setEmailCommentEnabled(request.getEmailCommentEnabled());
            }
            if (request.getEmailReplyEnabled() != null) {
                settings.setEmailReplyEnabled(request.getEmailReplyEnabled());
            }
            if (request.getEmailMentionEnabled() != null) {
                settings.setEmailMentionEnabled(request.getEmailMentionEnabled());
            }
            if (request.getEmailSystemEnabled() != null) {
                settings.setEmailSystemEnabled(request.getEmailSystemEnabled());
            }
            
            int result = notificationSettingsMapper.updateByUserId(settings);
            log.info("更新用户通知设置成功: userId={}, result={}", userId, result);
            return result > 0;
        } catch (Exception e) {
            log.error("更新用户通知设置失败: userId={}", userId, e);
            throw new RuntimeException("更新通知设置失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resetUserSettings(Long userId) {
        log.info("重置用户通知设置: userId={}", userId);
        try {
            // 删除现有设置
            notificationSettingsMapper.deleteById(
                notificationSettingsMapper.selectByUserId(userId).getId()
            );
            
            // 重新初始化
            return initUserSettings(userId);
        } catch (Exception e) {
            log.error("重置用户通知设置失败: userId={}", userId, e);
            throw new RuntimeException("重置通知设置失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean initUserSettings(Long userId) {
        log.info("初始化用户通知设置: userId={}", userId);
        try {
            // 检查是否已存在
            NotificationSettings existing = notificationSettingsMapper.selectByUserId(userId);
            if (existing != null) {
                log.info("用户通知设置已存在，跳过初始化: userId={}", userId);
                return true;
            }
            
            int result = notificationSettingsMapper.initUserSettings(userId);
            log.info("初始化用户通知设置成功: userId={}, result={}", userId, result);
            return result > 0;
        } catch (Exception e) {
            log.error("初始化用户通知设置失败: userId={}", userId, e);
            throw new RuntimeException("初始化通知设置失败", e);
        }
    }

    @Override
    public boolean isNotificationEnabled(Long userId, String notificationType) {
        try {
            NotificationSettings settings = notificationSettingsMapper.selectByUserId(userId);
            if (settings == null) {
                // 默认全部开启
                return true;
            }
            
            switch (notificationType) {
                case Notification.TYPE_FOLLOW:
                    return settings.getFollowEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_LIKE:
                    return settings.getLikeEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_COMMENT:
                    return settings.getCommentEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_REPLY:
                    return settings.getReplyEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_MENTION:
                    return settings.getMentionEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_SYSTEM:
                    return settings.getSystemEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_COLLECT:
                    return settings.getCollectEnabled() == NotificationSettings.ENABLED;
                default:
                    return true;
            }
        } catch (Exception e) {
            log.error("检查通知开关失败: userId={}, type={}", userId, notificationType, e);
            // 出错时默认开启
            return true;
        }
    }

    @Override
    public boolean isInDoNotDisturbPeriod(Long userId) {
        try {
            NotificationSettings settings = notificationSettingsMapper.selectByUserId(userId);
            if (settings == null || settings.getDoNotDisturbEnabled() == NotificationSettings.DISABLED) {
                return false;
            }
            
            LocalTime now = LocalTime.now();
            LocalTime start = settings.getDoNotDisturbStart();
            LocalTime end = settings.getDoNotDisturbEnd();
            
            if (start == null || end == null) {
                return false;
            }
            
            // 处理跨天情况
            if (start.isBefore(end)) {
                // 不跨天：start < now < end
                return now.isAfter(start) && now.isBefore(end);
            } else {
                // 跨天：now > start 或 now < end
                return now.isAfter(start) || now.isBefore(end);
            }
        } catch (Exception e) {
            log.error("检查免打扰时段失败: userId={}", userId, e);
            return false;
        }
    }

    @Override
    public boolean isWebSocketEnabled(Long userId) {
        try {
            NotificationSettings settings = notificationSettingsMapper.selectByUserId(userId);
            if (settings == null) {
                return true; // 默认开启
            }
            return settings.getWebsocketEnabled() == NotificationSettings.ENABLED;
        } catch (Exception e) {
            log.error("检查WebSocket开关失败: userId={}", userId, e);
            return true;
        }
    }

    @Override
    public boolean isEmailNotificationEnabled(Long userId, String notificationType) {
        try {
            NotificationSettings settings = notificationSettingsMapper.selectByUserId(userId);
            if (settings == null || settings.getEmailNotificationEnabled() == NotificationSettings.DISABLED) {
                return false;
            }
            
            switch (notificationType) {
                case Notification.TYPE_FOLLOW:
                    return settings.getEmailFollowEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_COMMENT:
                    return settings.getEmailCommentEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_REPLY:
                    return settings.getEmailReplyEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_MENTION:
                    return settings.getEmailMentionEnabled() == NotificationSettings.ENABLED;
                case Notification.TYPE_SYSTEM:
                    return settings.getEmailSystemEnabled() == NotificationSettings.ENABLED;
                default:
                    return false;
            }
        } catch (Exception e) {
            log.error("检查邮件通知开关失败: userId={}, type={}", userId, notificationType, e);
            return false;
        }
    }

    /**
     * 转换为响应DTO
     */
    private NotificationSettingsResponse convertToResponse(NotificationSettings settings) {
        NotificationSettingsResponse response = new NotificationSettingsResponse();
        BeanUtils.copyProperties(settings, response);
        
        // 转换Integer为Boolean
        response.setFollowEnabled(settings.getFollowEnabled() == NotificationSettings.ENABLED);
        response.setLikeEnabled(settings.getLikeEnabled() == NotificationSettings.ENABLED);
        response.setCommentEnabled(settings.getCommentEnabled() == NotificationSettings.ENABLED);
        response.setReplyEnabled(settings.getReplyEnabled() == NotificationSettings.ENABLED);
        response.setMentionEnabled(settings.getMentionEnabled() == NotificationSettings.ENABLED);
        response.setSystemEnabled(settings.getSystemEnabled() == NotificationSettings.ENABLED);
        response.setCollectEnabled(settings.getCollectEnabled() == NotificationSettings.ENABLED);
        response.setDoNotDisturbEnabled(settings.getDoNotDisturbEnabled() == NotificationSettings.ENABLED);
        response.setNotificationAggregationEnabled(settings.getNotificationAggregationEnabled() == NotificationSettings.ENABLED);
        response.setWebsocketEnabled(settings.getWebsocketEnabled() == NotificationSettings.ENABLED);
        response.setEmailNotificationEnabled(settings.getEmailNotificationEnabled() == NotificationSettings.ENABLED);
        response.setEmailFollowEnabled(settings.getEmailFollowEnabled() == NotificationSettings.ENABLED);
        response.setEmailCommentEnabled(settings.getEmailCommentEnabled() == NotificationSettings.ENABLED);
        response.setEmailReplyEnabled(settings.getEmailReplyEnabled() == NotificationSettings.ENABLED);
        response.setEmailMentionEnabled(settings.getEmailMentionEnabled() == NotificationSettings.ENABLED);
        response.setEmailSystemEnabled(settings.getEmailSystemEnabled() == NotificationSettings.ENABLED);
        
        return response;
    }
}

